library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
	
entity alu is
	port (
		opcode: IN STD_LOGIC_VECTOR (4 downto 0);
		A, B: IN STD_LOGIC_VECTOR (31 downto 0);
		output: OUT STD_LOGIC_VECTOR (31 downto 0);
		negative: OUT STD_LOGIC;
		overflow, zero: OUT STD_LOGIC);		
end alu;


architecture alu_arch of alu is
	constant alu_and	:  std_logic_vector(4 downto 0) := "00000";
	constant alu_add	:  std_logic_vector(4 downto 0) := "00001";
	constant alu_or 	:  std_logic_vector(4 downto 0) := "01000";
	constant alu_sub 	:  std_logic_vector(4 downto 0) := "01001";
	constant BAD1		:  std_logic_vector(31 downto 0) := x"1BADBAD1";
	signal tmp	:  std_logic_vector(31 downto 0);

	begin
	calc: process(A,B,opcode)
	begin
	   case opcode is	   
			when alu_add =>
				tmp <= A + B;		      
			when alu_sub =>			
				tmp <= A + not(B) + 1;						
			when alu_or =>
		   		tmp <= A OR B;
			when alu_and =>
   			   tmp <= A AND B;
			when others => 
				tmp <= BAD1;			
		end case;
	end process;
	overflow <= '1' when 
	   ((opcode=alu_add or opcode=alu_sub) and (A(31)=B(31)) AND (A(31)/=TMP(31)))
	            else '0';
	zero <= '1' when (tmp = x"00000000") else '0';
   negative<= tmp(31);
	output <= tmp(31 downto 0);
end alu_arch;
